#ifndef METANET_MQ_H
#define METANET_MQ_H

#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

#define MESSAGE_TYPE_MASK (SIZE_MAX>>8)
#define MESSAGE_TYPE_SHIFT ((sizeof(size_t)-1)*8)

struct metanet_message {
    uint32_t source;
    int session;
    void *data;
    size_t sz;
};

struct metanet_message_queue {
    uint32_t handle;
    int cap;
    int head;
    int tail;
    int release;
    int in_global;
    int priority;
    int overloaded;
    int overloaded_threshold;
    struct metanet_message *queue;
    struct metanet_message_queue *next;
};

struct metanet_global_message_queue {
    struct metanet_message_queue *head;
    struct metanet_message_queue *tail;
};

void metanet_globalmq_push(struct metanet_message_queue *queue);
void metanet_globalmq_push_head(struct metanet_message_queue *queue);
struct metanet_message_queue* metanet_globalmq_pop(void);

struct metanet_message_queue *metanet_mq_create(uint32_t handle);
void metanet_mq_mark_release(struct metanet_message_queue *queue);

typedef void (*message_drop)(struct metanet_message *msg, void *ud);
void metanet_mq_release(struct metanet_message_queue *queue, message_drop drop, void *ud);
uint32_t metanet_mq_handle(struct metanet_message_queue *queue);

int metanet_mq_pop(struct metanet_message_queue *queue, struct metanet_message *msg);
void metanet_mq_push(struct metanet_message_queue *queue, struct metanet_message *msg);

int metanet_mq_length(struct metanet_message_queue *queue);
int metanet_mq_overload(struct metanet_message_queue *queue);

void metanet_mq_init();

void metanet_mq_exit();

#endif // !METANET_MQ_H